package com.gzhryc.shared_device.oem.code.statistics.services;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.oem.code.statistics.dao.PlaceDayStatisticsDao;
import com.gzhryc.shared_device.oem.code.statistics.dao.db.PlaceDayStatistics;
import com.gzhryc.shared_device.oem.code.statistics.dao.models.PlaceSumMoneyData;
import com.gzhryc.shared_device.oem.code.statistics.services.dao.PlaceDayStatisticsSearch;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

public class PlaceDayStatisticsService {

    static Logger log = Logger.getLogger(PlaceDayStatisticsService.class);

    public static PlaceDayStatisticsService self() {
        return MultiDBTools.getService(PlaceDayStatisticsService.class, new Date());
    }

    public static PlaceDayStatisticsService self(Date date) {
        return MultiDBTools.getService(PlaceDayStatisticsService.class, date);
    }

    PlaceDayStatisticsDao dao;

    public PlaceDayStatisticsService(String jdbcKey,Date date) {
        dao = new PlaceDayStatisticsDao(jdbcKey,date);
    }

    public List<PlaceDayStatistics> findBySearch(PlaceDayStatisticsSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public Long countBySearch(PlaceDayStatisticsSearch search){
        Conditions conditions = dao.buildConditions(search);
        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return 0L;
    }

    public PlaceDayStatistics getOrAddByKeys(Long placeId,String placeName,String placeAreaName, Date createDate){
        if(placeId != null && createDate != null){
            String dayDate = DateFormatUtils.format(createDate,"yyyyMMdd");
            Conditions conditions = new Conditions(PlaceDayStatistics.class);
            conditions.and().is("placeId",placeId);
            conditions.and().is("dayDate",dayDate);
            try {
                PlaceDayStatistics statistics = dao.get(conditions);
                if(statistics != null){
                    return statistics;
                }else{
                    Integer yearNum = Integer.valueOf(DateFormatUtils.format(createDate, "yyyy"));
                    Integer monthNum = Integer.valueOf(DateFormatUtils.format(createDate, "MM"));
                    Integer dayNum = Integer.valueOf(DateFormatUtils.format(createDate, "dd"));
                    statistics = new PlaceDayStatistics();
                    statistics.setPlaceId(placeId);
                    statistics.setPlaceName(placeName);
                    statistics.setPlaceAreaName(placeAreaName);
                    statistics.setDayDate(dayDate);
                    statistics.setYearNum(yearNum);
                    statistics.setMonthNum(monthNum);
                    statistics.setDayNum(dayNum);
                    statistics.setCreateDate(createDate);

                    if(dao.insert(statistics) > 0){
                        return statistics;
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public List<PlaceSumMoneyData> sumGroupPlaceIdByYear(Integer yearNum,List<Long> placeIds){
        if(yearNum != null && placeIds != null && placeIds.size() > 0) {
            Conditions conditions = new Conditions(PlaceDayStatistics.class);
            conditions.and().is("yearNum", yearNum);
            conditions.and().in("placeId", placeIds);
            try {
                return dao.sumGroupPlaceIdByConditions(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public List<PlaceSumMoneyData> sumGroupPlaceIdByYearAndMonth(Integer yearNum,Integer monthNum,List<Long> placeIds){
        if(yearNum != null && monthNum != null && placeIds != null && placeIds.size() > 0) {
            Conditions conditions = new Conditions(PlaceDayStatistics.class);
            conditions.and().is("yearNum",yearNum);
            conditions.and().is("monthNum",monthNum);
            conditions.and().in("placeId", placeIds);
            try {
                return dao.sumGroupPlaceIdByConditions(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public void addOneOrderData(Long placeId,String placeName,String placeAreaName,Date createDate,Long orderMoney,Long orderPayMoney) {
        PlaceDayStatistics statistics = getOrAddByKeys(placeId,placeName,placeAreaName,createDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(PlaceDayStatistics.class);
            conditions.and().is("placeId", placeId);
            conditions.and().is("dayDate", statistics.getDayDate());

            PlaceDayStatistics updateEntity = new PlaceDayStatistics();
            updateEntity.setOrderCount(1);
            updateEntity.setOrderMoney(orderMoney);
            updateEntity.setOrderPayMoney(orderPayMoney);

            try {
                if (dao.updateNotNullAndInc(updateEntity, conditions, "orderCount", "orderMoney", "orderPayMoney") <= 0) {
                    log.error("修改网点统计(支付)失败，网点：{{0}}，时间：{{1}}", placeId, createDate);
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        } else {
            log.error("未找到或创建网点统计，网点：{{0}}，时间：{{1}}", placeId, createDate);
        }
    }

    public void addOneCancelData(Long placeId,String placeName,String placeAreaName,Date refundDate,Long cancelMoney,Date finishDate){
        PlaceDayStatistics statistics = getOrAddByKeys(placeId,placeName,placeAreaName,refundDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(PlaceDayStatistics.class);
            conditions.and().is("placeId", placeId);
            conditions.and().is("dayDate", statistics.getDayDate());

            //同一天则需要修改支付金额
            if (DateTools.isSameDay(refundDate, finishDate)) {
                PlaceDayStatistics updateEntity = new PlaceDayStatistics();
                updateEntity.setCancelOrderCount(1);
                updateEntity.setCancelOrderMoney(cancelMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "cancelOrderCount", "cancelOrderMoney") > 0) {
                        updateEntity = new PlaceDayStatistics();
                        updateEntity.setOrderPayMoney(cancelMoney);
                        dao.updateNotNullAndReduce(updateEntity, conditions, "orderPayMoney");
                    }else{
                        log.error("修改网点统计(撤销)失败，网点：{{0}}，时间：{{1}}", placeId, refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }else{
                PlaceDayStatistics updateEntity = new PlaceDayStatistics();
                updateEntity.setHistoryCancelOrderCount(1);
                updateEntity.setHistoryCancelOrderMoney(cancelMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "historyCancelOrderCount", "historyCancelOrderMoney") <= 0) {
                        log.error("修改网点统计(历史撤销)失败，时间：{{0}}", refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
        } else {
            log.error("未找到或创建网点统计，撤销统计失败，网点：{{0}}，时间：{{1}}", placeId, refundDate);
        }
    }

    public void addOneRefundData(Long placeId,String placeName,String placeAreaName,Date refundDate,Long refundMoney,Date finishDate){
        PlaceDayStatistics statistics = getOrAddByKeys(placeId,placeName,placeAreaName,refundDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(PlaceDayStatistics.class);
            conditions.and().is("placeId", placeId);
            conditions.and().is("dayDate", statistics.getDayDate());

            //同一天则需要修改支付金额
            if (DateTools.isSameDay(refundDate, finishDate)) {
                PlaceDayStatistics updateEntity = new PlaceDayStatistics();
                updateEntity.setOrderPayMoney(refundMoney);

                try {
                    if (dao.updateNotNullAndReduce(updateEntity, conditions, "orderPayMoney") <= 0) {
                        log.error("修改网点统计(退款)失败，时间：{{0}}", refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }else{
                PlaceDayStatistics updateEntity = new PlaceDayStatistics();
                updateEntity.setHistoryRefundOrderCount(1);
                updateEntity.setHistoryRefundOrderMoney(refundMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "historyRefundOrderCount", "historyRefundOrderMoney") <= 0) {
                        log.error("修改网点统计(历史退款)失败，时间：{{0}}", refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
        } else {
            log.error("未找到或创建网点统计，退款统计失败，网点：{{0}}，时间：{{1}}", placeId, refundDate);
        }
    }
}
